/**
 ***********************************************************************************************************
 * Class in charge of managing lights
 ***********************************************************************************************************
 * @file RBLight.h
 ***********************************************************************************************************/

#ifndef __RBLIGHT_H__
#define __RBLIGHT_H__

#ifdef  HEADER_ONCE
#pragma HEADER_ONCE
#endif

#ifdef  HEADER_MSG
#pragma HEADER_MSG(RBLight.h)
#endif

/***********************************************************************************************************
 * Includes
 ***********************************************************************************************************/
#include "RBTSpatialComponent.h"

/***********************************************************************************************************
 * Forward declarations
 ***********************************************************************************************************/
class RBGeometry;

/***********************************************************************************************************
 * Classes
 ***********************************************************************************************************/

RBDeclareHandle(RBLight);

class RBLight : public RBTSpatialComponent<RBLight>
{
public:
    RB_DECLARE_COMPONENT(RBLight)

    enum LightType
    {
        LT_POINT = 0,
        LT_SPOT,
        LT_AMBIENT,
        LT_DIRECTIONAL
    };


				        RBLight                     (RBEntityHandle entityHandle, RBTransformComponentHandle xForm);
    virtual            ~RBLight                     ();

    LightType           GetType                     () const { return m_eLightType; }
    void                SetType                     (LightType eLightType) { m_eLightType = eLightType; }

    //////////////////////////////////////////////////////////////////////////
    // Accessors for all light types
    //////////////////////////////////////////////////////////////////////////
    const RBColor&      GetColor                    () const { return m_kColor; }
    float               GetMultiplier               () const { return m_fMultiplier; }

    void                SetColor                    (const RBColor& kColor) { m_kColor = kColor; }
    void                SetMultiplier               (float fMultiplier)       { m_fMultiplier = fMultiplier; }
    //////////////////////////////////////////////////////////////////////////

    //////////////////////////////////////////////////////////////////////////
    // Accessors for point and spot lights
    //////////////////////////////////////////////////////////////////////////
    float               GetConstantAttenuation      () const { return m_fConstantAttenuation; }
    float               GetLinearAttenuation        () const { return m_fLinearAttenuation; }
    float               GetQuadraticAttenuation     () const { return m_fQuadraticAttenuation; }

    void                SetConstantAttenuation      (float fConstantAttenuation)  { m_fConstantAttenuation = fConstantAttenuation; }
    void                SetLinearAttenuation        (float fLinearAttenuation)    { m_fLinearAttenuation = fLinearAttenuation; }
    void                SetQuadraticAttenuation     (float fQuadraticAttenuation) { m_fQuadraticAttenuation = fQuadraticAttenuation; }
    //////////////////////////////////////////////////////////////////////////

    //////////////////////////////////////////////////////////////////////////
    // Accessors for spot lights only
    //////////////////////////////////////////////////////////////////////////
    float               GetPenumbraAngle            () const { return m_fPenumbraAngle; }
    float               GetUmbraAngle               () const { return m_fUmbraAngle; }
    float               GetFalloff                  () const { return m_fFalloff; }

    void                SetPenumbraAngle            (float fPenumbraAngle)  { m_fPenumbraAngle = fPenumbraAngle; }
    void                SetUmbraAngle               (float fUmbraAngle)     { m_fUmbraAngle = fUmbraAngle; }
    void                SetFalloff                  (float fFalloff)        { m_fFalloff = fFalloff; }
    //////////////////////////////////////////////////////////////////////////

    float3              GetDirection                () const;

    void                AddGeometry                 (RBGeometry* pAffectedGeometry);
    void                RemoveGeometry              (RBGeometry* pAffectedGeometry);

    virtual void        Serialize                   (RBStream& kStream);

    void                CopyMembers                 (RBLightHandle handleDest);

private:
    LightType           m_eLightType;
    RBColor             m_kColor;
    float               m_fMultiplier;
    float               m_fConstantAttenuation;
    float               m_fLinearAttenuation;
    float               m_fQuadraticAttenuation;
    float               m_fPenumbraAngle;
    float               m_fUmbraAngle;
    float               m_fFalloff;
    std::set<RBGeometry*> m_aGeometries;
};

RBDeclareSmartPointer(RBLight);

/***********************************************************************************************************/

#endif // __RBLIGHT_H__
